#-*- coding:utf-8 -*-
'''
Created on 2012-7-11

@author: johnny
'''
import Queue
import json
import os.path
import threading
import listener
from db import databases
from utils import zmq_client
import vm, vm_exceptions

BASE_MSG = {
            'id': '',
            'action': 0,
            'option_type': 'VmnoclusterchangeTask',
            'param': {}
            }

DEFAULT_MSG_PORT = 9166

RESULT_QUEUE = Queue.Queue()

class Message():
    def __init__(self):
        self.msg = BASE_MSG
        self.param = {}
    
    def set_param(self, param):
        self.msg['param'] = param
    
    def add_param(self, key, value):
        self.param[key] = value
        self.msg['param'] = self.param
    
    def set_value(self, key, value):
        if key in self.msg.keys():
            self.msg[key] = value
        else:
            print "BuildMsg -- set_value: invalid key"
    
    def get_msg(self):
        return json.dumps(self.msg)
    
class Executer(object):
    def __init__(self):
        #self.result = Queue.Queue()
        self.terminate = threading.Event()
        try:
            self.listener = listener.Listener(RESULT_QUEUE, self.terminate)
            self.listener.setDaemon(True)
            self.listener.start()
        except Exception:
            pass
            
    def run(self, action, params, host_ip, port=DEFAULT_MSG_PORT):
        message = Message()
        message.set_param(params)
        message.set_value('action', action)
        print message.get_msg()
        return self.send(message.get_msg(), host_ip, port)
        
    def send(self, message, host, port):
        #sending
        self.recv_msg = zmq_client.zmq_sender(message, host, port)
        return self.recv_msg
    
#    def stop(self):
#        self.terminate.set()
#        if self.listener.isAlive():
#            self.send("stop", "localhost", 9081)
#        print "Executer: stop() "
    
    def wait_for_done(self, timeout=60):
        #wait for finished
        try:
            msg = RESULT_QUEUE.get(True, timeout)
        except Queue.Empty:
            raise vm_exceptions.OperationTimeoutException(timeout)
        if msg == "actionResult":
            print "wait_for_done:", msg
            return msg

 
class Commander(object):
    def __init__(self):
        self.executor = Executer()
        self.vm = vm.VMBase()
    
#    def teardown(self):
#        if self.executor.listener.isAlive():
#            self.executor.stop()
            
    def create(self, vm, host, storage='defaultlocal', img=None):
        self.vm = vm
        qurey = databases.DBQuery(host, user="postgres")
        
        keyword = "description=\'" + storage + "\'"
        if not qurey.get_storagepath(keyword):
            raise vm_exceptions.MCommonException("Storage not found")
        
        self.vm.cfg['storage_path'] = qurey.get_storagepath(keyword)
        self.vm.cfg['storage_uuid'] = qurey.get_storageUuid(keyword)
        self.vm.cfg['hostUuid'] = qurey.get_hostUuid()
        
        if not img:
            self.vm.set_default_img()
        else:
            self.vm.hard_drive['baseimg'] = img
            self.vm.hard_drive['createvhd'] = "no"
            print self.vm.hard_drive['baseimg']
                   
        self.vm.cfg['hd'].append(vm.hard_drive)
        self.vm.cfg['netcardAllPara'].append(vm.netcard)        
        self.executor.run(500, vm.cfg, host)
        self.executor.wait_for_done(120)
        vm.initialize(host, storage, self.executor)
        
    def delete_vm(self, host, vm, del_vhd=False):
        params = {}
        self.vm = vm
        params['vmUuid'] = self.vm.get_vmUuid()
        params['storage_path'] = self.vm.cfg['storage_path']
        params['parentUuid'] = self.vm.cfg['hostUuid']
        if del_vhd:
            params['delvhd'] = 'delvhd'
        else:
            params['delvhd'] = 'savevhd'
        self.executor.run(502, params, host)
        self.executor.wait_for_done(120)
    
    def add_storage(self, host, name, storagetype, is_mount, storage_param):
        qurey = databases.DBQuery(host, user="postgres")
        params = {}
        params['storageName'] = name
        params['hostUuid'] = qurey.get_hostUuid()
        params['storageType'] = storagetype
        params['isMount'] = is_mount
        params['storagePar'] = storage_param
        self.executor.run(200, params, host)
        self.executor.wait_for_done(120)
        
    
    def get_img_path(self, host, storage, name):
        query = databases.DBQuery(host, user="postgres")
        keyword = "description=\'" + storage + "\'"
        path = os.path.join(query.get_storagepath(keyword), name)
        path = path.replace('\\', '/')
        return path
        
    def reboot_host(self, host):
        param = {}
        query = databases.DBQuery(host, user="postgres")
        hostUuid = query.get_hostUuid()
        if hostUuid:
            param['hostUuid'] = hostUuid
        else:
            #TBD
            return
            
        self.executor.run(305, param)   
    